using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Repositories
{
    /// <summary>
    /// 增强的仓储基类
    /// 结合了Repository和SimpleRepository的功能
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    public abstract class EnhancedRepository<T> : Repository<T> where T : class
    {
        protected EnhancedRepository(CmsDbContext.LowCodeDbContext context) : base(context)
        {
        }

        /// <summary>
        /// 根据规范查询实体
        /// </summary>
        /// <param name="specification">查询规范</param>
        /// <returns>实体列表</returns>
        public virtual async Task<List<T>> FindBySpecificationAsync(ISpecification<T> specification)
        {
            var query = ApplySpecification(_dbSet.AsQueryable(), specification);
            return await query.ToListAsync();
        }

        /// <summary>
        /// 根据规范查询单个实体
        /// </summary>
        /// <param name="specification">查询规范</param>
        /// <returns>实体或null</returns>
        public virtual async Task<T?> FindSingleBySpecificationAsync(ISpecification<T> specification)
        {
            var query = ApplySpecification(_dbSet.AsQueryable(), specification);
            return await query.FirstOrDefaultAsync();
        }

        /// <summary>
        /// 根据规范分页查询
        /// </summary>
        /// <param name="specification">查询规范</param>
        /// <returns>分页结果</returns>
        public virtual async Task<(List<T> Items, int Total)> GetPagedBySpecificationAsync(ISpecification<T> specification)
        {
            var query = ApplySpecification(_dbSet.AsQueryable(), specification);
            
            var totalCount = await (specification.IsPagingEnabled 
                ? ApplySpecificationWithoutPaging(_dbSet.AsQueryable(), specification).CountAsync()
                : query.CountAsync());

            var items = await query.ToListAsync();
            return (items, totalCount);
        }

        /// <summary>
        /// 应用规范到查询
        /// </summary>
        /// <param name="query">原始查询</param>
        /// <param name="specification">查询规范</param>
        /// <returns>应用规范后的查询</returns>
        protected virtual IQueryable<T> ApplySpecification(IQueryable<T> query, ISpecification<T> specification)
        {
            if (specification.Criteria != null)
                query = query.Where(specification.Criteria);

            // 应用Include
            query = specification.Includes.Aggregate(query, (current, include) => current.Include(include));
            query = specification.IncludeStrings.Aggregate(query, (current, include) => current.Include(include));

            // 应用排序
            if (specification.OrderBy != null)
                query = query.OrderBy(specification.OrderBy);
            else if (specification.OrderByDescending != null)
                query = query.OrderByDescending(specification.OrderByDescending);

            // 应用分组
            if (specification.GroupBy != null)
                query = query.GroupBy(specification.GroupBy).SelectMany(g => g);

            // 应用分页
            if (specification.IsPagingEnabled)
            {
                query = query.Skip(specification.Skip).Take(specification.Take);
            }

            return query;
        }

        /// <summary>
        /// 应用规范到查询（不包含分页）
        /// </summary>
        protected virtual IQueryable<T> ApplySpecificationWithoutPaging(IQueryable<T> query, ISpecification<T> specification)
        {
            if (specification.Criteria != null)
                query = query.Where(specification.Criteria);

            query = specification.Includes.Aggregate(query, (current, include) => current.Include(include));
            query = specification.IncludeStrings.Aggregate(query, (current, include) => current.Include(include));

            if (specification.OrderBy != null)
                query = query.OrderBy(specification.OrderBy);
            else if (specification.OrderByDescending != null)
                query = query.OrderByDescending(specification.OrderByDescending);

            if (specification.GroupBy != null)
                query = query.GroupBy(specification.GroupBy).SelectMany(g => g);

            return query;
        }

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="entities">实体列表</param>
        public virtual async Task BulkInsertAsync(IEnumerable<T> entities)
        {
            await _dbSet.AddRangeAsync(entities);
            await SaveChangesAsync();
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="entities">实体列表</param>
        public virtual async Task BulkUpdateAsync(IEnumerable<T> entities)
        {
            _dbSet.UpdateRange(entities);
            await SaveChangesAsync();
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="entities">实体列表</param>
        public virtual async Task BulkDeleteAsync(IEnumerable<T> entities)
        {
            _dbSet.RemoveRange(entities);
            await SaveChangesAsync();
        }
    }
}
